package com.yztstudy.Service.Impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yztstudy.Service.SearchService;
import com.yztstudy.entity.Product;
import com.yztstudy.param.ProductSearchParam;
import com.yztstudy.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class SearchServiceImpl implements SearchService {

    @Resource
    private RestHighLevelClient restHighLevelClient;

    /**
     * TODO 分页 + 分词 的商品搜索
     * @param productSearchParam 商品搜索
     * @return
     */
    @Override
    public R search(ProductSearchParam productSearchParam){

        // TODO 1.构造请求查询体
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.indices("product");

        // TODO 2.如果搜索内容为null或者空字符串,则查询全部
        SearchSourceBuilder builder = new SearchSourceBuilder();
        if (StringUtils.isEmpty(productSearchParam.getSearch()))
        {
            builder.query(QueryBuilders.matchAllQuery());
        }

        // TODO 3.否则,添加all的关键字匹配
        else {
            builder.query(QueryBuilders.matchQuery("all", productSearchParam.getSearch()).operator(Operator.OR));
        }

        // TODO 4.封装请求
        builder.from((productSearchParam.getCurrentPage() - 1) * productSearchParam.getPageSize()); // 起始页码
        builder.size(productSearchParam.getPageSize()); // 每一页的大小
        searchRequest.source(builder);

        // TODO 5.发送查询请求
        SearchResponse searchResponse = null;
        try {
            searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // TODO 6.解析响应结果
        SearchHits hits = searchResponse.getHits(); // 查询的总条数
        Long total = hits.getTotalHits().value;

        List<Product> products = new ArrayList<>();
        ObjectMapper objectMapper = new ObjectMapper();
        for (SearchHit hit : hits)
        {
            String objectJSON = hit.getSourceAsString();
            Product product = null;
            try {
                product = objectMapper.readValue(objectJSON, Product.class);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            products.add(product);
        }

        // TODO 7.返回结果
        log.info("SearchServiceImpl.search业务结束, 结果:{}", "ES服务器查询成功!");
        return R.ok("ES服务器查询成功!", products, total);
    }
}
